package cn.simple.base.support;

import cn.simple.base.component.BaseJFrame;
import cn.simple.game.Game;
import lombok.Getter;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 游戏加载器
 */
@Getter
public class GameApplication {

    private static final String CLASS_SUFFIX = ".class";

    private final Class<?> tClass;

    private List<Game> gameList;

    public GameApplication(Class<?> tClass) {
        this.tClass = tClass;
        refresh();
    }

    public void refresh() {
        //获取所有游戏实现类
        gameList = getGameList();
        //加载游戏
        loadGame(gameList);
    }

    public void loadGame(List<Game> gameList) {
        BaseJFrame baseJFrame = new BaseJFrame("基础界面");
        //布局
        JPanel layoutPanel = new JPanel(new GridLayout(gameList.size() + 1, 1));

        //游戏列表
        JLabel label = new JLabel("游戏列表");
        label.setFont(new Font("楷体", Font.BOLD, 30));

        JPanel flowPanel = new JPanel(new FlowLayout());
        flowPanel.add(label);
        layoutPanel.add(flowPanel);

        gameList.stream().filter(Game::isLoad).forEach(o -> {
            JPanel jPanel = new JPanel(new FlowLayout());
            JButton gameButton = new JButton(o.getName());
            gameButton.addActionListener(e -> {
                o.display();
                baseJFrame.setVisible(false);
            });
            jPanel.add(gameButton);
            layoutPanel.add(jPanel);
        });

        baseJFrame.add(layoutPanel);
        baseJFrame.setVisible(true);

    }

    private List<Game> getGameList() {
        return this.getGameClasses().stream().map(o -> {
            try {
                return o.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());
    }

    private List<Class<Game>> getGameClasses() {
        //找出所有java文件，并过滤出Game接口的子类
        return findJavaFiles().stream().map(this::defineClass).filter(Objects::nonNull)
                .filter(c ->
                        Arrays.stream(c.getInterfaces()).anyMatch(o -> Objects.equals(o.getTypeName(), Game.class.getTypeName()))
                ).map(o -> (Class<Game>) o).collect(Collectors.toList());
    }

    private List<File> findJavaFiles() {
        //工作路径
        String workPath = System.getProperty("user.dir");
        File folder = new File(workPath);
        return getFolderAllJavaFile(folder);
    }

    private List<File> getFolderAllJavaFile(File file) {
        if (file.isFile()) {
            return file.getName().endsWith(CLASS_SUFFIX) ? Collections.singletonList(file) : new ArrayList<>();
        }
        List<File> fileList = new ArrayList<>();
        //找出所有java文件
        File[] files = file.listFiles();
        if (files != null) {
            for (File innerFile : files) {
                fileList.addAll(getFolderAllJavaFile(innerFile));
            }
        }
        return fileList;
    }

    private Class<?> defineClass(File file) {
        return new ClassLoader() {
            public Class<?> getClass(File file) {
                try (FileInputStream is = new FileInputStream(file)) {
                    byte[] bytes = new byte[(int) file.length()];
                    is.read(bytes);
                    return defineClass(null, bytes, 0, bytes.length);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
        }.getClass(file);
    }

}
